package me.acomma.groot.application.role;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import me.acomma.groot.infrastructure.Pagination;
import me.acomma.groot.domain.menu.MenuRepository;
import me.acomma.groot.domain.role.Role;
import me.acomma.groot.domain.role.RoleId;
import me.acomma.groot.domain.role.RoleRepository;
import me.acomma.groot.domain.user.UserId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Objects;

@Component
public class RoleApplicationService {
    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private MenuRepository menuRepository;

    @Autowired
    private RoleAssembler roleAssembler;

    public RoleData get(Long roleId) {
        Role role = roleRepository.get(RoleId.of(roleId));
        return roleAssembler.toRoleData(role);
    }

    @Transactional(rollbackFor = {Exception.class})
    public void create(CreateRoleCommand command) {
        Role role = new Role();
        role.setRoleId(roleRepository.nextId());
        role.setName(command.getName());
        roleRepository.add(role);
    }

    @Transactional(rollbackFor = {Exception.class})
    public void modify(ModifyRoleCommand command) {
        Role role = roleRepository.get(RoleId.of(command.getRoleId()));
        if (Objects.isNull(role)) {
            throw new IllegalStateException("角色不存在");
        }
        role.setName(command.getName());
        roleRepository.update(role);
    }

    @Transactional(rollbackFor = {Exception.class})
    public void remove(RemoveRoleCommand command) {
        Role role = roleRepository.get(RoleId.of(command.getRoleId()));
        if (Objects.isNull(role)) {
            return;
        }
        long count = menuRepository.countByRoleId(RoleId.of(command.getRoleId()));
        if (count > 0) {
            throw new IllegalStateException("请先移除角色的菜单信息");
        }
        roleRepository.remove(RoleId.of(command.getRoleId()));
    }

    public List<RoleData> getAll() {
        List<Role> roles = roleRepository.getAll();
        return roleAssembler.toRoleDataList(roles);
    }

    public Pagination<RoleData> pageQuery(PageQueryRoleCommand command) {
        Role role = roleAssembler.toRole(command);
        Page<Role> page = PageHelper.startPage(command.getPageNumber(), command.getPageSize());
        List<Role> roles = roleRepository.pageQuery(role);
        return new Pagination<>(command.getPageNumber(), command.getPageSize(), page.getTotal(), roleAssembler.toRoleDataList(roles));
    }

    public List<RoleData> getRoleByUserId(Long userId) {
        List<Role> roles = roleRepository.getByUserId(UserId.of(userId));
        return roleAssembler.toRoleDataList(roles);
    }

    @Transactional(rollbackFor = {Exception.class})
    public void assignMenu(AssignMenuCommand command) {
        roleRepository.removeRoleMenuByRoleId(new RoleId(command.getRoleId()));
        if (!CollectionUtils.isEmpty(command.getMenuIds())) {
            roleRepository.addRoleMenu(command.getRoleId(), command.getMenuIds());
        }
    }
}
